﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace Kaskelot.SP.UI.Analys.ViewModel
{
	public class CheckboxQueryBuilderViewModel : INotifyPropertyChanged
	{
		public CheckboxQueryBuilderViewModel()
		{
			this.Query = new Query();
			this.Query.PropertyChanged += Query_PropertyChanged;
			this.SavedQueries = new List<Query>();
		}

		void Query_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
		{
			if (e.PropertyName == "Entities")
			{
				DisableFields();
				OnPropertyChanged("HasEntitySelected");
				OnPropertyChanged("PrimaryEntity");
				OnPropertyChanged("RelatedEntities");
				OnPropertyChanged("Query");
			}
		}

		public void DisableFields()
		{
			foreach (Entity ent in this.Query.Entities.Where(e => !e.Checked))
			{
				ent.Fields.ForEach(fi => fi.Checked = false);
			}
		}

		private Query query;
		public Query Query
		{
			get
			{
				return this.query;
			}
			set
			{
				if (value != null)
				{
					this.query = value;
					this.query.PropertyChanged += Query_PropertyChanged;
					//this.PrimaryEntity = this.query.Entities.FirstOrDefault(e => e.IsPrimary);
					OnPropertyChanged("HasEntitySelected");
					OnPropertyChanged("PrimaryEntity");
					OnPropertyChanged("RelatedEntities");
					OnPropertyChanged("Query");
					OnPropertyChanged("SelectedEntities");
				}
			}
		}

		public List<Query> SavedQueries { get; set; }

		private Entity primaryEntity;
		public Entity PrimaryEntity
		{
			get
			{
				return this.primaryEntity;
			}

			set
			{
				if (value != null)
				{
					if (primaryEntity != null && primaryEntity != value)
					{
						this.Reset();
					}

					this.primaryEntity = value;

					this.Query.Entities.ForEach(e => e.IsPrimary = false);
					this.Query.Entities.Single(e => e.Name == this.primaryEntity.Name).IsPrimary = true;
					this.Query.Entities.Single(e => e.Name == this.primaryEntity.Name).Checked = true;

					this.Query.Entities.Where(entity => this.primaryEntity.CannotBeCombinedWith.Any(name => name == entity.Name))
						.ToList().ForEach((Entity incompatibleEntity) =>
						{
							incompatibleEntity.Checked = false;
							incompatibleEntity.IsEnabled = false;
							incompatibleEntity.Fields.ForEach((Field f) =>
							{
								f.Checked = false;
							});
						});
					OnPropertyChanged("HasEntitySelected");
					OnPropertyChanged("PrimaryEntity");
					OnPropertyChanged("RelatedEntities");
					OnPropertyChanged("Query");
					OnPropertyChanged("SelectedEntities");
				}
			}
		}

		public List<Entity> RelatedEntities
		{
			get
			{
				return this.Query.Entities.Where(e => this.PrimaryEntity != null && e.IsEnabled && e.Name != this.PrimaryEntity.Name).ToList();
			}
		}

		public List<Entity> SelectedEntities
		{
			get
			{
				return this.Query.Entities.Where(e => e.Checked).ToList();
			}
		}

		public bool HasEntitySelected
		{
			get
			{
				return this.Query.Entities.Any(e => e.Checked);
			}
		}

		private bool selectionModeSelectQuery;
		public bool SelectionModeSelectQuery
		{
			get
			{
				return this.selectionModeSelectQuery;
			}
			set
			{
				this.selectionModeSelectQuery = value;
				OnPropertyChanged("SelectionModeSelectQuery");
			}
		}

		public event PropertyChangedEventHandler PropertyChanged;
		private void OnPropertyChanged(string propertyname)
		{
			if (PropertyChanged != null)
				PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
		}

		public void Reset()
		{
			this.query.Entities.ForEach(e =>
			{
				e.Checked = false;
				e.IsEnabled = true;
				e.Fields.ForEach(f => f.Checked = false);
			});

			this.primaryEntity = null;
			this.Query.Filters.Clear();
			this.Query.Name = String.Empty;
			this.Query.ID = 0;
			this.Query.IsPersonal = true;
			this.RelatedEntities.Clear();

			OnPropertyChanged("HasEntitySelected");
			OnPropertyChanged("PrimaryEntity");
			OnPropertyChanged("RelatedEntities");
			OnPropertyChanged("Query");
			OnPropertyChanged("SelectedEntities");
		}
	}
}
